package com.moco.launcher.link;

import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;

import com.moco.launcher.dialog.WaitDialog;
import com.moco.launcher.listener.EventCallback;
import com.oazon.common.SettingType;
import com.oazon.common.Settings;
import com.oazon.common.util.DataFormat;
import com.oazon.moco.bean.McServiceMsg;
import com.oazon.moco.bean.Metadata;
import com.oazon.moco.bean.PlayStatus;
import com.oazon.moco.bean.VolumeChannel;
import com.oazon.moco.lan.core.controldriver.bean.ControlDriver;
import com.oazon.moco.lan.core.http.bean.AVTransportUri;
import com.oazon.moco.lan.core.http.bean.CurrentPlayMode;
import com.oazon.moco.lan.core.http.bean.DeleteBean;
import com.oazon.moco.lan.core.http.bean.FavoriteBean;
import com.oazon.moco.lan.core.http.bean.MediaStateInstance;
import com.oazon.moco.lan.core.http.bean.PositionInfo;
import com.oazon.moco.lan.core.http.bean.ResponseUriToQueue;
import com.oazon.moco.lan.core.http.bean.ResponseVolume;
import com.oazon.moco.lan.core.http.bean.Seek;
import com.oazon.moco.lan.core.http.bean.SeekUnit;
import com.oazon.moco.lan.core.http.bean.TransportState;
import com.oazon.moco.lan.core.http.bean.UriToQueue;
import com.oazon.moco.lan.core.http.bean.Volume;
import com.oazon.moco.lan.core.http.bean.VolumeInstance;
import com.oazon.moco.lan.core.http.bean.ZoneInfo;
import com.oazon.moco.lan.util.WifiManageUtil;
import com.oazon.moco.link.SaveMediaState;
import com.oazon.moco.link.bean.BatteryInfo;
import com.oazon.moco.link.bean.Mcu;
import com.oazon.moco.link.core.LinkEvent;
import com.oazon.moco.link.core.LinkEventController;
import com.oazon.moco.link.core.LinkEventListener;
import com.oazon.moco.link.core.LinkSDK;
import com.oazon.moco.link.core.source.LinkEventSource;
import com.oazon.moco.link.event.BatteryEvent;
import com.oazon.moco.link.event.BatteryStatus;
import com.oazon.moco.link.event.ResponceEvent;
import com.oazon.moco.link.event.ResponceStatus;
import com.oazon.moco.link.event.SpechEvent;
import com.oazon.moco.link.event.SpeechStatus;
import com.oazon.moco.link.ui.LanEventListener;
import com.oazon.moco.link.ui.PlayEventListener;
import com.oazon.moco.link.ui.RequestEventListener;
import com.oazon.moco.link.ui.SystemStateEventListener;
import com.oazon.moco.playlist.PlayListManage;
import com.oazon.moco.playlist.bean.PlayListCurrentMode;
import com.oazon.system.bean.SystemState;

/**
 * 界面和播放器对接事件的类
 * 
 * @author Gavin
 *
 */
public class LinkManager {

	private static final String TAG = "LinkManager";

	private Context mCtx = null;
	private volatile static LinkManager instance;
	private EventCallback mCb = null;

	private SystemState saveSystemState = SystemState.NORMAL;

	private PowerManager pm = null;

	// private static AllSatus saveAllSatus = new AllSatus();

	public SystemState getSaveSystemState() {
		return saveSystemState;
	}

	/** Returns singleton class instance */
	public static LinkManager getInstance() {
		if (instance == null) {
			synchronized (LinkManager.class) {
				if (instance == null) {
					instance = new LinkManager();
				}
			}
		}
		return instance;
	}

	private LinkManager() {
	}

	public void init(Context ctx) {
		mCtx = ctx;
		LinkSDK.init(mCtx);
		LinkSDK linkSDK = LinkSDK.getInstance();
		linkSDK.registLinkListener(playEventListener);
		linkSDK.registLinkListener(SpechEventListener);
		linkSDK.registLinkListener(batteryEventListener);
		linkSDK.registLinkListener(responseListener);
		linkSDK.registLinkListener(wifi_getlistener);
		linkSDK.registLinkListener(requestListener);
		linkSDK.registLinkListener(systemStateEventListener);
		linkSDK.registLinkListener(requestListener_serail);
		linkSDK.registLinkListener(lanEventListener);
		linkSDK.openService(LinkEventController.uiSource, LinkSDK.PORT);

		// 添加强制点亮屏幕
		pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
		
		List<Volume> volumes = new ArrayList<Volume>();
		Volume volume = new Volume();
		volume.setChannel(VolumeChannel.MASTER);
		volume.setVal(Settings.getInstance(mCtx).getInt(SettingType.VOLUME.value(), 13));
		volumes.add(volume);
		SaveMediaState.getInstance().setVolume(volumes);
		SaveMediaState.getInstance().setCurrentPlayMode(CurrentPlayMode.NORMAL);
		SaveMediaState.getInstance().setRelTime("0:00:00");
		SaveMediaState.getInstance().setTransportState(TransportState.STOPPED);
	}

	public void pauseUiEvent() {

	}

	public void destrory() {
		LinkSDK.destroy();
	}

	/**
	 * 媒体状态的改变通知
	 */
	private synchronized void notifyMediaState() {
		LinkSDK.getInstance().notyfiStateChange(LinkEventController.uiSource,
				SaveMediaState.getInstance().getMediaStateInstance());

	}

	/**
	 * gethardversion
	 */
	public synchronized void getHardWareVersion() {
		LinkSDK.getInstance().requestHardWareVersion(
				LinkEventController.uiSource);
	}

	public synchronized void setNormal() {
		if (saveSystemState == SystemState.SCREEN_PROTECT
				|| saveSystemState == SystemState.STANDBY) {
			mCb.finishScreenProtectActivity();
		}
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	public synchronized void setScreenProtect() {
		LinkSDK.getInstance().isScreenProtect(LinkEventController.uiSource);
	}

	public synchronized void addUriToQueueResponse(LinkEventSource source,
			ResponseUriToQueue responseUriToQueue) {
		LinkSDK.getInstance().addUriToQueueResponse(source, responseUriToQueue);
	}

	public synchronized void setShutdone() {
		LinkSDK.getInstance().isShutdone(LinkEventController.uiSource);
	}

	public synchronized void setOpendone() {
		LinkSDK.getInstance().isOpendone(LinkEventController.uiSource);
	}

	public synchronized void setStandby() {
		LinkSDK.getInstance().isWait(LinkEventController.uiSource);
	}

	public synchronized void play() {
		SaveMediaState.getInstance().setTransportState(TransportState.PLAYING);
		notifyMediaState();
	}

	public void pause() {
		SaveMediaState.getInstance().setTransportState(
				TransportState.PAUSED_PLAYBACK);
		notifyMediaState();
	}

	public void stopSppech() {
		LinkSDK.getInstance().speechStop(LinkEventController.uiSource);
	}

	public void previous() {
		// LinkSDK.getInstance().previous(LinkEventController.uiSource);
	}

	public void next() {
		// LinkSDK.getInstance().next(LinkEventController.uiSource);
	}

	public void curSongInfo(Metadata metadata, long duration) {
		if (metadata == null) {
			return;
		}
		Log.d(TAG, "duration===" + duration);
		SaveMediaState.getInstance().setTransportState(TransportState.PLAYING);
		MediaStateInstance.Instance instance = SaveMediaState.getInstance()
				.getFirstMediaStateInstance();
		instance.setRelTime("0:00:00");
		instance.setCurrentTrackDuration(DataFormat.formatDuring(duration));
		instance.setCurrentTrack(PlayListManage.getInstance().getReadIndex());
		instance.setCurrentTrackMetaData(metadata);
		metadata.getRes().setDuration(DataFormat.formatDuring(duration));
		if (PlayListManage.getInstance().getSaveCurrentMode() == PlayListCurrentMode.QUEUE) {
			instance.setCurrentTransportActions("Set,Play,Stop,Pause,Seek,Next,Previous");
		} else if (PlayListManage.getInstance().getSaveCurrentMode() == PlayListCurrentMode.SMART_RADIO) {
			instance.setCurrentTransportActions("Set,Play,Stop,Pause,Seek,Next,Previous");
		}
		
		if(PlayListManage.getInstance().size() == 1){
			instance.setCurrentTransportActions("Set,Play,Stop,Pause,Seek");
		}
		
		SaveMediaState.getInstance().setMediaStateInstance(instance);
		notifyMediaState();
	}

	public void favorite(FavoriteBean favoriteBean) {
	/*	LinkSDK.getInstance().favorite(LinkEventController.uiSource,
				favoriteBean);*/
		try {
			SaveMediaState.getInstance().getFirstMediaStateInstance().getCurrentTrackMetaData().setFavorite(favoriteBean.isLike());
			notifyMediaState();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void delete(DeleteBean deleteBean) {
		LinkSDK.getInstance().delete(LinkEventController.uiSource, deleteBean);
	}
	
	public void setProgress(long prog) {
		saveProgress(prog);
		notifyMediaState();
	}

	public void setPlayMode(CurrentPlayMode playMode) {
		SaveMediaState.getInstance().setCurrentPlayMode(playMode);
		notifyMediaState();
	}

	public void startSpeak(String str) {
		LinkSDK.getInstance().speechStartSpeakString(
				LinkEventController.uiSource, str);
	}

	/**
	 * 保存进度值
	 * 
	 * @param progress
	 */
	public void saveProgress(long progress) {
		String time = DataFormat.formatDuring(progress);
		SaveMediaState.getInstance().setRelTime(time);
	}

	public void registerCallback(EventCallback cb) {
		mCb = cb;
	}

	private LanEventListener lanEventListener = new LanEventListener(
			LinkEventController.uiSource) {

		@Override
		public void subscribe(final ControlDriver controlDriver) {
			super.subscribe(controlDriver);
			Log.d(TAG, "" + "subscribe==" + controlDriver.getIp() + ":"
					+ controlDriver.getPort() + "\r\n");
		}

		@Override
		public void unsubscribe(final ControlDriver controlDriver) {
			super.unsubscribe(controlDriver);
			Log.d("Gavin", "mainactivity=========unsubscribe");
			Log.d(TAG, "" + "unsubscribe==" + controlDriver.getIp() + "\r\n");

		}
		
		@Override
		public void serviceAdded(McServiceMsg msg,String uuid) {
			mCb.serviceAdded(msg,uuid);
		}

		@Override
		protected void serviceDelete(String serviceName,String uuid, ChannelHandlerContext ctx) {
			mCb.serviceDelete(serviceName,uuid,ctx);
		}
	};

	private PlayEventListener playEventListener = new PlayEventListener(
			LinkEventController.uiSource) {

		@Override
		protected void delete(String uuid, DeleteBean deleteBean,
				ChannelHandlerContext ctx) {
			mCb.delete(deleteBean, ctx);
		}

		@Override
		protected void favorite(String uuid, FavoriteBean favoriteBean,ChannelHandlerContext ctx) {
			
			mCb.favorite(favoriteBean,ctx);
		}

		@Override
		protected ResponseUriToQueue addUriToQueue(String uuid,
				UriToQueue uriToQueue, LinkEventSource linkEventSource) {
			Log.d(TAG, "addUriToQueue==" + uriToQueue.toString());

			ResponseUriToQueue result = mCb.addUriToQueue(uuid, uriToQueue,
					linkEventSource);
			if (!TransportState.PLAYING.equals(SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getTransportState())) {
				mCb.playStart(false);
				SaveMediaState.getInstance().setTransportState(
						TransportState.PLAYING);
			}
			return result;
		}

		@Override
		protected void setAVTransportUri(String uuid,
				AVTransportUri avTransportUri) {
			Log.d(TAG, "setAVTransportUri=="
					+ PlayListManage.getInstance().getSaveCurrentMode()
							.toString());
			mCb.avTransport(avTransportUri);
			if (!TransportState.PLAYING.equals(SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getTransportState())) {
				mCb.playStart(false);
				SaveMediaState.getInstance().setTransportState(
						TransportState.PLAYING);
			}
		}

		@Override
		protected void setPlayShift(String uuid) {
			Log.d(TAG, "" + "setPlayShift" + "\r\n");
			if (TransportState.PLAYING.equals(SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getTransportState())) {
				mCb.playPause(true);
				SaveMediaState.getInstance().setTransportState(
						TransportState.PAUSED_PLAYBACK);
			} else {
				mCb.playStart(true);
				SaveMediaState.getInstance().setTransportState(
						TransportState.PLAYING);
			}

		}

		@Override
		protected void play(String uuid, int instanceID, int speed) {
			Log.d(TAG, "" + "play" + "\r\n");

			SaveMediaState.getInstance().setTransportState(
					TransportState.TRANSITIONING);
			LinkSDK.getInstance().notyfiStateChange(
					LinkEventController.uiSource,
					SaveMediaState.getInstance().getMediaStateInstance());

			mCb.playStart(false);

/*			SaveMediaState.getInstance().setTransportState(
					TransportState.PLAYING);
			LinkSDK.getInstance().notyfiStateChange(
					LinkEventController.uiSource,
					SaveMediaState.getInstance().getMediaStateInstance());*/
		}

		@Override
		protected void pause(String uuid) {
			Log.d(TAG, "" + "playPause" + "\r\n");
			SaveMediaState.getInstance().setTransportState(
					TransportState.PAUSED_PLAYBACK);
			mCb.playPause(true);

		}

		@Override
		protected void stop(String uuid) {
			Log.d(TAG, "" + "stop" + "\r\n");
			mCb.playStop();
		}

		@Override
		protected void next(String uuid) {
			Log.d(TAG, "" + "next" + "\r\n");
			mCb.playNext();
		}

		@Override
		protected void playMode(String uuid, final String playMode) {
			Log.d(TAG, "" + "playMode==" + playMode + "\r\n");
			mCb.playMode(playMode);
		}

		@Override
		protected void setVolume(String uuid, VolumeInstance volumeInstance) {
			try {
				Log.d(TAG, "setVolume=="
						+ volumeInstance.getVolume().get(0).getVal());

				List<Volume> volumes = new ArrayList<Volume>();

				for (Volume volume : volumeInstance.getVolume()) {
					Volume object = new Volume();
					object.setChannel(volume.getChannel());
					object.setVal(volume.getVal() * 100 / 32);
					volumes.add(object);
				}
				SaveMediaState.getInstance().setVolume(volumes);
				
				if (volumeInstance != null
						&& volumeInstance.getVolume() != null
						&& volumeInstance.getVolume().get(0) != null) {
					
					Settings.getInstance(mCtx).setInt(
							SettingType.VOLUME.value(),
							volumeInstance.getVolume().get(0).getVal());
					mCb.setVolume(volumeInstance.getVolume().get(0).getVal());
					
				}
			} catch (Exception e) {

			}
		}

		@Override
		protected void setProgress(String uuid, Seek seek) {
			Log.d(TAG, "seek==" + seek.getTarget());
			if (SeekUnit.REL_TIME == seek.getUnit()) {
				mCb.seekTo(DataFormat.valueOfdate(seek.getTarget()));
				SaveMediaState.getInstance().setRelTime(seek.getTarget());
			}
			if (SeekUnit.TRACK_NR == seek.getUnit()) {
				mCb.toPlayItem(Integer.parseInt(seek.getTarget()));
			}
		}

		@Override
		protected void previous(String uuid) {
			Log.d(TAG, "" + "previous==" + "\r\n");
			mCb.playPrev();
		}
	};

	@SuppressLint("DefaultLocale")
	public static String byteToString(byte[] b) {
		StringBuffer buffer = new StringBuffer(b.length);
		for (int i = 0; i < b.length; i++) {
			String strHex = Integer.toHexString(b[i]).toUpperCase();
			if (strHex.length() > 3) {
				buffer.append(strHex.substring(6) + " ");
			} else if (strHex.length() < 2) {
				buffer.append("0" + strHex + " ");
			} else {
				buffer.append(strHex + " ");
			}
		}
		return buffer.toString();
	}

	/*
	 * private ResponceEventListener responseListener = new
	 * ResponceEventListener( LinkEventController.uiSource) {
	 * 
	 * };
	 */

	private com.oazon.moco.link.serialport.RequestEventListener requestListener_serail = new com.oazon.moco.link.serialport.RequestEventListener(
			LinkEventController.serialSource);

	private RequestEventListener requestListener = new RequestEventListener(
			LinkEventController.uiSource) {

		@Override
		protected MediaStateInstance getAllStatus(int instanceID) {
			return SaveMediaState.getInstance().getMediaStateInstance();
		}

		@Override
		protected PositionInfo getPositionInfo(int instanceID) {
			PositionInfo positionInfo = new PositionInfo();
			positionInfo.setRelTime(SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getRelTime());
			positionInfo.setTrackMetadata(SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getCurrentTrackMetaData());
			return positionInfo;
		}

		@Override
		protected ZoneInfo getVersion(ZoneInfo zoneInfo) {
			ZoneInfo info = new ZoneInfo();
			info.setCopyrightInfo("2014-2015 O2 Inc. All Rights Reserved.");
			info.setDisplaySoftwareVersion("5.2");
			info.setExtraInfo("OTP: 1.1.1(1-16-4-zp5s-0.5)");
			info.setHardwareVersion("1.16.4.1-2");
			WifiManageUtil wifiManageUtil = new WifiManageUtil(mCtx);
			info.setIPAddress(wifiManageUtil.getIP().getHostAddress());
			info.setMACAddress(wifiManageUtil.getMac());
			info.setSerialNumber(LinkSDK.UUID);
			info.setSoftwareVersion("28.1-83040");
			return info;
		}

		@Override
		protected String getPlayStatus() {
			if (TransportState.PAUSED_PLAYBACK == SaveMediaState.getInstance()
					.getFirstMediaStateInstance().getTransportState()
					|| TransportState.STOPPED == SaveMediaState.getInstance()
							.getFirstMediaStateInstance().getTransportState()) {
				return PlayStatus.PAUSE;
			} else {
				return PlayStatus.PLAY;
			}
		}

		@Override
		protected ResponseVolume getVolume(int instanceID) {
			// TODO Auto-generated method stub
			return super.getVolume(instanceID);
		}

	};

	private LinkEventListener responseListener = new LinkEventListener(
			LinkEventController.uiSource) {

		@Override
		public void onLinkEvent(LinkEvent event) {

		}
	};

	private LinkEventListener wifi_getlistener = new LinkEventListener(
				LinkEventController.uiSource) {

			@Override
			public void onLinkEvent(LinkEvent event) {

				if (filter((LinkEventSource) event.getSource())) {
					return;
				}
				if (event instanceof ResponceEvent) {
					ResponceEvent e = (ResponceEvent) event;

					if (e.getResponceStatus().equals(
							ResponceStatus.HARDWARE_VERSION)) {
						Mcu.mcu_verison = e.getHardwareVersion();
						Log.i("mcu_version", e.getHardwareVersion());
						// Toast.makeText(mCtx, "版本号："+e.getHardwareVersion(),
						// Toast.LENGTH_SHORT).show();
					}

				}
			}

	};

	private LinkEventListener batteryEventListener = new LinkEventListener(
			LinkEventController.uiSource) {

		@Override
		public void onLinkEvent(LinkEvent event) {
			if (filter((LinkEventSource) event.getSource())
					|| !(event instanceof BatteryEvent)) {
				return;
			}
			final BatteryEvent e = (BatteryEvent) event;
			if (null != e.getState()) {
				if (e.getState().equals(BatteryStatus.EXTERNAL_POWER_IN)) {
					BatteryInfo.isDC = true;
				} else if (e.getState()
						.equals(BatteryStatus.EXTERNAL_POWER_OUT)) {
					BatteryInfo.isDC = false;
				} else if (e.getState().equals(BatteryStatus.CHARGE_ON)) {
					BatteryInfo.IsCharging = true;
				} else if (e.getState().equals(BatteryStatus.CHARGE_OFF)) {
					BatteryInfo.IsCharging = false;
				} else if (e.getState().equals(BatteryStatus.CHARGE_PERCNET)) {
					BatteryInfo.ChargePercent = e.getCharge_percent();
					mCb.batteryChange(e.getCharge_percent());
				} else if (e.getState().equals(BatteryStatus.Battery_LOW)) {
					BatteryInfo.isLowPower = true;
				}else if(e.getState().equals(BatteryStatus.BATTERY_VOLTAGE)){
					BatteryInfo.voltage = e.getVoltage();
				}
				Log.d(TAG, "" + "serialPort===电池状态：" + e.getState() + "\r\n");
			}
		}
	};

	private LinkEventListener SpechEventListener = new LinkEventListener(
			LinkEventController.uiSource) {

		@Override
		public void onLinkEvent(LinkEvent event) {
			if (filter((LinkEventSource) event.getSource())
					|| !(event instanceof SpechEvent)) {
				return;
			}
			SpechEvent e = (SpechEvent) event;

			if (e.getSpechStatus() == SpeechStatus.SPEECHSTART) {
				LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
				Log.d(TAG, "语音开始");
				mCb.speechStart();
			}
		}
	};

	private SystemStateEventListener systemStateEventListener = new SystemStateEventListener() {

		@Override
		protected void hasAction() {
			Log.d(TAG, "hasAction");
			if (saveSystemState == SystemState.SCREEN_PROTECT
					|| saveSystemState == SystemState.STANDBY) {
				mCb.finishScreenProtectActivity();
			}
			saveSystemState = SystemState.NORMAL;
			super.hasAction();
		}

		@Override
		protected void normal() {
			if (saveSystemState == SystemState.SCREEN_PROTECT
					|| saveSystemState == SystemState.STANDBY) {
				mCb.finishScreenProtectActivity();
			}
			Log.e(TAG, "亮屏");
			try {
				pm.wakeUp(SystemClock.uptimeMillis());
			} catch (Exception e) {
				Log.e(TAG, "亮屏，是否有权限" + e.getMessage());
			}
			saveSystemState = SystemState.NORMAL;
			super.normal();
		}

		@Override
		protected void opendown() {
			saveSystemState = SystemState.NORMAL;
			super.opendown();
		}

		@Override
		protected void screenProtect() {
			saveSystemState = SystemState.SCREEN_PROTECT;
			mCb.showScreenProtectFlagment();
			super.screenProtect();
		}

		@Override
		protected void shutdown() {
			Log.e(TAG, "关机");
			saveSystemState = SystemState.SHUTDOWN;
			try {
				shutDown();
				WaitDialog dialog = WaitDialog.createDialog(mCtx);
				dialog.setMessage("正在关机...");
			} catch (Exception e) {
				Log.e(TAG, "关机，是否有权限" + e.getMessage());
			}

			super.shutdown();
		}

		@Override
		protected void shutdownOpenCancle() {
			// TODO Auto-generated method stub
			super.shutdownOpenCancle();
		}

		@Override
		protected void shutdownToOpenTime(int shutdownToOpenTime) {
			super.shutdownToOpenTime(shutdownToOpenTime);
		}

		@Override
		protected void waite() {
			Log.e(TAG, "暗屏");
			try {
				Log.e(TAG, "暗屏lock");
				pm.goToSleep(SystemClock.uptimeMillis());
			} catch (Exception e) {
				Log.e(TAG, "暗屏，是否有权限" + e.getMessage());
			}

			saveSystemState = SystemState.STANDBY;
			super.waite();
		}

	};
	public static final String ACTION_REBOOT = "android.intent.action.REBOOT";
	public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";
	public static final String CONFIRM = "android.intent.action.EXTRA_KEY_CONFIRM";

	private void shutDown() {
		/*
		Intent shutdown = new Intent(ACTION_REQUEST_SHUTDOWN);
		shutdown.putExtra(CONFIRM, false);
		shutdown.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_NEW_TASK);
		mCtx.startActivity(shutdown);*/
	}

}
